 
package com.zdkj.subway.rca.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;

import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.google.common.collect.Lists;

import com.zdkj.subway.rca.dto.out.SwCkConfiirmProcessItvmEpaymentDTO;
import com.zdkj.subway.rca.entity.SwCkConfiirmProcessItvmEpayment;
import com.zdkj.subway.rca.mapper.SwCkConfiirmProcessItvmEpaymentMapper;
import com.zdkj.subway.rca.service.SwCkConfiirmProcessItvmEpaymentService;

import com.zdkj.subway.rca.util.excel.SwAuInternetTicketEquipmentLineExcelColumnWidthStrategy;
import com.zdkj.subway.rca.util.excel.SwAuInternetTicketEquipmentLineExcelHorizontalCellStyleStrategy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 对账确认过程-ITVM支付表
 *
 * @author stw
 * @date 2020-10-26 15:13:52
 */
@Service
public class SwCkConfiirmProcessItvmEpaymentServiceImpl extends ServiceImpl<SwCkConfiirmProcessItvmEpaymentMapper, SwCkConfiirmProcessItvmEpayment> implements SwCkConfiirmProcessItvmEpaymentService {
    private static final Logger log = LoggerFactory.getLogger(SwCkConfiirmProcessItvmEpaymentServiceImpl.class);
    public List<SwCkConfiirmProcessItvmEpayment> listSwCkConfiirmProcessItvmEpayment(String startDate, String endDate, String confirmStatus, String ordflag) {
        List<SwCkConfiirmProcessItvmEpayment>  list = this.baseMapper.listSwCkConfiirmProcessItvmEpayment(startDate,endDate,confirmStatus,ordflag);
        for (SwCkConfiirmProcessItvmEpayment swCkConfiirmProcessItvmEpayment : list) {
            String url = "/rca/swckbankverifypayment/previewDiff?tradeDateStr=_tradeDateStr_&verfiyConfirmFlag=_verfiyConfirmFlag_";
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String dateStr = swCkConfiirmProcessItvmEpayment.getTradeDate().format(fmt);
            if(swCkConfiirmProcessItvmEpayment.getDiffMoney() != 0) {
                if("1".equals(swCkConfiirmProcessItvmEpayment.getTitle())) {
                    swCkConfiirmProcessItvmEpayment.setDiffBankUrl(url.replace("_tradeDateStr_",dateStr).replace("_verfiyConfirmFlag_","8"));
                }
                else if("2".equals(swCkConfiirmProcessItvmEpayment.getTitle())) {
                    swCkConfiirmProcessItvmEpayment.setDiffAlipayUrl(url.replace("_tradeDateStr_",dateStr).replace("_verfiyConfirmFlag_","6"));
                }
                else if("3".equals(swCkConfiirmProcessItvmEpayment.getTitle())) {
                    swCkConfiirmProcessItvmEpayment.setDiffWechartUrl(url.replace("_tradeDateStr_",dateStr).replace("_verfiyConfirmFlag_","7"));
                }
            }
        }
        return list;
    }

    /**
     * 导出
     * @param
     * @return
     * @throws IOException
     */
    @Override
    public void exportExcel(String startDate, String endDate,String confirmStatus, String ordflag, HttpServletResponse response) {

        List<SwCkConfiirmProcessItvmEpayment> list  = this.baseMapper.listSwCkConfiirmProcessItvmEpayment(startDate,endDate,confirmStatus,ordflag);
        BigDecimal hundred = new BigDecimal(100);
        List<SwCkConfiirmProcessItvmEpaymentDTO> records = new ArrayList<>();
        List<Map<String,String>>  listMap = this.baseMapper.getLineGroupList();
        for (SwCkConfiirmProcessItvmEpayment obj : list) {
            SwCkConfiirmProcessItvmEpaymentDTO dto = new SwCkConfiirmProcessItvmEpaymentDTO();
            dto.setTradeDate(obj.getTradeDate());
            dto.setMoney(new BigDecimal(obj.getMoney()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setServiceCharge(new BigDecimal(obj.getServiceCharge()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setBankMoney(new BigDecimal(obj.getBankMoney()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            dto.setDiffMoney(new BigDecimal(obj.getDiffMoney()).divide(hundred,2,BigDecimal.ROUND_HALF_UP));
            if("1".equals(obj.getTitle())) {
                dto.setTitle("建行");
            }
            else  if("2".equals(obj.getTitle())) {
                dto.setTitle("支付宝");
            }
            else  if("3".equals(obj.getTitle())) {
                dto.setTitle("微信");
            }

            dto.setLineGroup(getLineGoupName(listMap,obj.getLineGroup()));
            dto.setConfirmStatus("1".equals(obj.getConfirmStatus()) ? "已确认" : "未确认");
            records.add(dto);
        }
        
        
        List<SwCkConfiirmProcessItvmEpaymentDTO> lineTilteList = getLineTilteList(records);

        List<String> dateList = getDateList(records);
		Collections.sort(dateList);  //日期排序，为了正序显示
		//log.info("排序后的值==="+dateList+"--------------"+dateList.toString());

        // 表格数据
        List<List<Object>> dataList = getDataList(records,lineTilteList,dateList);

        try {response.reset(); // 非常重要
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            final String fileName = URLEncoder.encode("ITVM支付数据", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                    // 设置统一的表头、表内容样式
                    .registerWriteHandler(SwAuInternetTicketEquipmentLineExcelHorizontalCellStyleStrategy.style())
                    // 设置表头，表内容的行高

                    .registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 20, (short) 20))
                    .build();

            WriteSheet writeSheet = EasyExcel.writerSheet(0, "ITVM支付数据")
                    .registerWriteHandler(new SwAuInternetTicketEquipmentLineExcelColumnWidthStrategy())
                    // 自定义多级复杂表头
                    .head(getHead(lineTilteList))
                    .build();

            excelWriter.write(dataList, writeSheet);
            excelWriter.finish();

        } catch (IOException e) {
            e.printStackTrace();
            log.error("导出ITVM支付数据错误");
        }

    }

    private String getLineGoupName(List<Map<String,String>> listMap,String value) {

        for(Map<String,String> map : listMap){
            if(value.equals(map.get("value"))){
                return map.get("label");
            }
        }
        return "";
    }


    /**
     * @param records
     * @return
     */
    private List<SwCkConfiirmProcessItvmEpaymentDTO> getLineTilteList(List<SwCkConfiirmProcessItvmEpaymentDTO> records) {

        Set<SwCkConfiirmProcessItvmEpaymentDTO> set = new LinkedHashSet<>();
        for (SwCkConfiirmProcessItvmEpaymentDTO obj : records){
            SwCkConfiirmProcessItvmEpaymentDTO swCkConfiirmProcessItvmEpayment = new SwCkConfiirmProcessItvmEpaymentDTO();
            swCkConfiirmProcessItvmEpayment.setLineGroup(obj.getLineGroup());
            swCkConfiirmProcessItvmEpayment.setTitle(obj.getTitle());
            set.add(swCkConfiirmProcessItvmEpayment);
        }
        List<SwCkConfiirmProcessItvmEpaymentDTO> list = new ArrayList<>(set);
        return list;
    }

    private List<String> getDateList(List<SwCkConfiirmProcessItvmEpaymentDTO> records){
        Set<String> set = new LinkedHashSet<>();
        for (SwCkConfiirmProcessItvmEpaymentDTO obj : records) {
            DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String dateStr = obj.getTradeDate().format(fmt);
            set.add(dateStr);
        }
        List<String> list = new ArrayList<>(set);
        return list;
    }

    /**
     * getDataList
     * @param records
     * @return
     */
    private List<List<Object>> getDataList(List<SwCkConfiirmProcessItvmEpaymentDTO> records, List<SwCkConfiirmProcessItvmEpaymentDTO> lineTilteList,List<String> dateList) {
        List<List<Object>> dataList = new ArrayList<>();


        //处理数据行
        for (String dateStr : dateList) {

            List<Object> list = new ArrayList<>();
            list.add(dateStr);

            for (SwCkConfiirmProcessItvmEpaymentDTO lineTilte : lineTilteList) {
                BigDecimal money = new BigDecimal(0.00);
                BigDecimal serviceCharge = new BigDecimal(0.00);
                BigDecimal bankMoney = new BigDecimal(0.00);

                for (SwCkConfiirmProcessItvmEpaymentDTO obj : records) {
                    if (dateStr.equals(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(obj.getTradeDate()))
                            && lineTilte.getLineGroup().equals(obj.getLineGroup())
                            && lineTilte.getTitle().equals(obj.getTitle())) {
                        money = obj.getMoney();
                        serviceCharge = obj.getServiceCharge();
                        bankMoney = obj.getBankMoney();

                        break;
                    }
                }
                list.add(money);
                list.add(serviceCharge);
                list.add(bankMoney);
            }

            String confirmStatus = "已确认";

            //差值
            for (SwCkConfiirmProcessItvmEpaymentDTO lineTilte : lineTilteList) {
                BigDecimal diffMoney = new BigDecimal(0.00);
                for (SwCkConfiirmProcessItvmEpaymentDTO obj : records) {
                    if (dateStr.equals(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(obj.getTradeDate()))
                            && lineTilte.getLineGroup().equals(obj.getLineGroup())
                            && lineTilte.getTitle().equals(obj.getTitle())) {
                        diffMoney = obj.getDiffMoney();
                        if("未确认".equals(obj.getConfirmStatus())) { //有一个未确认就是未确认
                            confirmStatus = "未确认";
                        }
                        break;
                    }
                }
                list.add(diffMoney);
            }

            //确认状态
            list.add(confirmStatus);

            dataList.add(list);
        }

        //处理最后行的合计
        List<Object> list = new ArrayList<>();
        list.add("合计");

        for (SwCkConfiirmProcessItvmEpaymentDTO lineTilte : lineTilteList) {
            BigDecimal totalMoney = new BigDecimal(0.00);
            BigDecimal totalServiceCharge = new BigDecimal(0.00);
            BigDecimal totalBankMoney = new BigDecimal(0.00);

            for (String dateStr : dateList){
                for(SwCkConfiirmProcessItvmEpaymentDTO obj : records){
                    if(dateStr.equals(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(obj.getTradeDate()))
                            && lineTilte.getLineGroup().equals(obj.getLineGroup())
                            && lineTilte.getTitle().equals(obj.getTitle())){
                        totalMoney = totalMoney.add(obj.getMoney());
                        totalServiceCharge = totalServiceCharge.add(obj.getServiceCharge());
                        totalBankMoney = totalBankMoney.add(obj.getBankMoney());
                        break;
                    }
                }
            }

            list.add(totalMoney);
            list.add(totalServiceCharge);
            list.add(totalBankMoney);
        }

        //差值合计
        for (SwCkConfiirmProcessItvmEpaymentDTO lineTilte : lineTilteList) {
            BigDecimal totalDiffMoney = new BigDecimal(0.00);

            for (String dateStr : dateList) {
                for (SwCkConfiirmProcessItvmEpaymentDTO obj : records) {
                    if (dateStr.equals(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(obj.getTradeDate()))
                            && lineTilte.getLineGroup().equals(obj.getLineGroup())
                            && lineTilte.getTitle().equals(obj.getTitle())) {
                        totalDiffMoney = totalDiffMoney.add(obj.getDiffMoney());
                        break;
                    }
                }
            }

            list.add(totalDiffMoney);
        }
        list.add("--");
        dataList.add(list);
        return dataList;
    }

    /**
     * 得到表头
     * @param
     * @return
     */
    private static List<List<String>> getHead(List<SwCkConfiirmProcessItvmEpaymentDTO> lineTilteList) {

        List<List<String>> headTitles = Lists.newArrayList();

        String title = "支付宝、微信、银联交易统计表:", dateStr = "日期",confirmStatus = "状态",empty = "";

        //第一列，1/2/3/4行
        headTitles.add( Lists.newArrayList(title,dateStr) );

        for (SwCkConfiirmProcessItvmEpaymentDTO lineTilte : lineTilteList) {
            headTitles.add( Lists.newArrayList(title,lineTilte.getLineGroup(), lineTilte.getTitle(),"交易金额") );
            headTitles.add( Lists.newArrayList(title,lineTilte.getLineGroup(), lineTilte.getTitle(),"手续费") );
            headTitles.add( Lists.newArrayList(title,lineTilte.getLineGroup(), lineTilte.getTitle(),"银行存款") );
        }

        //差值
        for (SwCkConfiirmProcessItvmEpaymentDTO lineTilte : lineTilteList) {
            headTitles.add( Lists.newArrayList(title,"差异（交易-银行）",lineTilte.getLineGroup(), lineTilte.getTitle()) );
        }

        headTitles.add( Lists.newArrayList(title,"状态") );

        return headTitles;

    }



}
